#!/bin/bash

# 文件备份脚本
# 功能：将A目录中的文件全量打包后备份到B目录，使用时间戳命名，并删除2天前的备份文件

# ========================================
# 配置参数 - 请根据实际情况修改以下路径
# ========================================

# 源目录路径（A目录）- 用户上传文件的目录
SOURCE_DIR="/data/wwwroot/tongji-api/storage/uploads"

# 备份目标目录路径（B目录）- 备份文件存储的目录
BACKUP_BASE_DIR="/mnt/data/tongji-uploads-backup"

# 备份保留天数
BACKUP_RETENTION_DAYS=2

# 是否启用日志记录
ENABLE_LOGGING=true

# 备份文件命名前缀
BACKUP_PREFIX="backup"

# 压缩格式 (gz, bz2, xz)
COMPRESSION_TYPE="gz"

# ========================================
# 脚本逻辑部分
# ========================================

# 日志文件路径
LOG_FILE="${BACKUP_BASE_DIR}/backup.log"

# 获取当前时间戳 (格式: YYYYMMDDHH)
TIMESTAMP=$(date +"%Y%m%d%H")

# 备份文件名
BACKUP_FILE_NAME="${BACKUP_PREFIX}_${TIMESTAMP}.tar.${COMPRESSION_TYPE}"

# 完整的备份文件路径
BACKUP_FILE="${BACKUP_BASE_DIR}/${BACKUP_FILE_NAME}"

# 记录日志的函数
log_message() {
    if [ "$ENABLE_LOGGING" = true ]; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
    fi
}

# 检查源目录是否存在
if [ ! -d "$SOURCE_DIR" ]; then
    log_message "错误：源目录 $SOURCE_DIR 不存在"
    exit 1
fi

# 创建备份基础目录（如果不存在）
if [ ! -d "$BACKUP_BASE_DIR" ]; then
    mkdir -p "$BACKUP_BASE_DIR"
    log_message "创建备份基础目录: $BACKUP_BASE_DIR"
fi

# 开始备份
log_message "开始备份操作..."
log_message "源目录: $SOURCE_DIR"
log_message "备份文件: $BACKUP_FILE"

# 检查源目录是否为空
if [ -z "$(ls -A "$SOURCE_DIR" 2>/dev/null)" ]; then
    log_message "警告：源目录为空，跳过备份"
    exit 0
fi

# 执行打包备份
log_message "开始打包源目录..."

# 根据压缩类型选择tar命令参数
case "$COMPRESSION_TYPE" in
    "gz")
        COMPRESS_FLAG="z"
        ;;
    "bz2")
        COMPRESS_FLAG="j"
        ;;
    "xz")
        COMPRESS_FLAG="J"
        ;;
    *)
        log_message "错误：不支持的压缩类型 $COMPRESSION_TYPE，使用gz"
        COMPRESS_FLAG="z"
        COMPRESSION_TYPE="gz"
        ;;
esac

# 切换到源目录的父目录，以便在打包时保持相对路径
SOURCE_PARENT_DIR=$(dirname "$SOURCE_DIR")
SOURCE_DIR_NAME=$(basename "$SOURCE_DIR")

cd "$SOURCE_PARENT_DIR" || {
    log_message "错误：无法切换到源目录的父目录"
    exit 1
}

# 执行tar打包命令
if tar -c${COMPRESS_FLAG}f "$BACKUP_FILE" "$SOURCE_DIR_NAME" 2>/dev/null; then
    log_message "备份完成: $BACKUP_FILE"
    
    # 显示备份文件大小
    if command -v du >/dev/null 2>&1; then
        BACKUP_FILE_SIZE=$(du -sh "$BACKUP_FILE" 2>/dev/null | cut -f1)
        log_message "备份文件大小: $BACKUP_FILE_SIZE"
    fi
else
    log_message "错误：备份失败"
    exit 1
fi

# 删除指定天数前的备份文件
log_message "开始清理旧备份文件..."

# 计算指定天数前的时间戳
DAYS_AGO=$(date -d "$BACKUP_RETENTION_DAYS days ago" +"%Y%m%d%H")

# 查找并删除旧备份文件
find "$BACKUP_BASE_DIR" -type f -name "${BACKUP_PREFIX}_*.tar.${COMPRESSION_TYPE}" | while read file; do
    file_name=$(basename "$file")
    # 提取时间戳部分
    file_timestamp=$(echo "$file_name" | sed "s/${BACKUP_PREFIX}_//" | sed "s/\.tar\.${COMPRESSION_TYPE}$//")
    
    # 如果文件时间戳小于等于指定天数前的时间戳，则删除
    if [ "$file_timestamp" -le "$DAYS_AGO" ]; then
        log_message "删除旧备份: $file"
        rm -f "$file"
    fi
done

log_message "备份操作完成"
log_message "----------------------------------------"

# 显示备份统计信息
BACKUP_COUNT=$(find "$BACKUP_BASE_DIR" -type f -name "${BACKUP_PREFIX}_*.tar.${COMPRESSION_TYPE}" | wc -l)
log_message "当前备份数量: $BACKUP_COUNT"

# 显示磁盘使用情况
if command -v du >/dev/null 2>&1; then
    BACKUP_SIZE=$(du -sh "$BACKUP_BASE_DIR" 2>/dev/null | cut -f1)
    log_message "备份目录总大小: $BACKUP_SIZE"
fi
